/*********************************************************************************
* Copyright (c) zhujinyang.
* All rights reserved.
*
* \file
*
* rh850 can chip driver
*
* 
*********************************************************************************/
#ifndef HAL_CANFD_DRV_H
#define HAL_CANFD_DRV_H



typedef enum {
    CAN_COM_1,
    CAN_COM_2,
    CAN_COM_3,
    CAN_COM_MAX
} CAN_COM_E;


typedef enum {
    CAN_WORKMODE_NORMAL,         
    CAN_WORKMODE_LISTEN,         
    CAN_WORKMODE_LOOPBACK,       
    CAN_WORKMODE_MAX
} CAN_WORK_MODE_E;

typedef enum {
    CAN_ERROR_NOERROR      = 0,
    CAN_ERROR_NOACK        = 3,      /* No Ack Error */
    CAN_ERROR_STUFF        = 1,      /* Stuff Error */
    CAN_ERROR_FORM         = 2,      /* Form Error */
    CAN_ERROR_BIT1         = 4,      /* Recessive Bit Error */
    CAN_ERROR_BIT0         = 5,      /* Dominant Bit Error */
    CAN_ERROR_CRC          = 6,      /* CRC Error */
    CAN_ERROR_BUSOFF       = 30,     /* BUFOFF, self-defined special value */
    CAN_ERROR_MAX
} CAN_ERROR_E;



typedef struct {
    INT32U  baseid;    /* bit31 stands for extended frame */
    INT32U  maskid;
} CAN_FILTER_T;

typedef struct {
    INT32U  id;         /* bit31 stands for extended frame */
    INT32U  dlc;          
    INT32U  data[16];
} CAN_DATA_T;


/**********************************************************************************
* \brief:       open a can channel
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \param[in]:   nominal_buad:    CAN using baud rate EX.500k->buadrate:500 000
* \param[in]:   nominal_samplepoint: Actual value of sampling point * 100, for example 80%->8000, suport: 75%, 81.25%, 87.5%, 80%, 85%, 90%
* \param[in]:   data_buad:    CAN using baud rate EX.5000k->buadrate:5000 000; if it is 0, no canfd
* \param[in]:   data_samplepoint: Actual value of sampling point * 100, for example 80%->8000, suport: 75%, 81.25%, 87.5%, 80%, 85%, 90%
* \param[in]:   workmode:    see "CAN_WORK_MODE_E"
* \param[in]:   p_filter:    Receive CAN mask
* \param[in]:   cfgnum:      the number of mask, 0: Receive all packets without filtering, including standard frame extension frames
* \return:      success : 0, < 0 : abnormal
**********************************************************************************/
INT32S hal_can_opencom(INT32U com, 
                       INT32U nominal_buad, 
                       INT32U nominal_samplepoint, 
                       INT32U data_buad, 
                       INT32U data_samplepoint, 
                       INT32U workmode, 
                       const CAN_FILTER_T *p_filter, 
                       INT32U cfgnum);


/**********************************************************************************
* \brief:       close the current channel
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \return:      -1: abnormal, success: 0
**********************************************************************************/
INT32S hal_can_closecom(INT32U com);

/**********************************************************************************
* \brief:       Get whether the current channel is opened
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \return:      true / false
**********************************************************************************/
BOOLEAN hal_can_isopened(INT32U com);


/**********************************************************************************
* \brief:       Read CAN data
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \param[in]:   id: can id
* \param[in]:   data: The storage address of the send data, must align 4 bytes.
* \param[in]:   dlc: send data length
* \return:      -1: abnormal, success: Send error count value, range 0-255
* \note:        For efficient data copying, please align the parameter "data" with 4 bytes.
**********************************************************************************/
INT32S hal_can_senddata(INT32U com, INT32U id, INT8U dlc, INT8U *data);



/**********************************************************************************
* \brief:       Get whether the current channel is send success
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \return:      true / false
**********************************************************************************/
INT32S hal_can_issendsuccess(INT32U com);


/**********************************************************************************
* \brief:       Get whether the bus is in the busoff state
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \return:      true / false
**********************************************************************************/
BOOLEAN hal_can_isbusoff(INT32U com);



/**********************************************************************************
* \brief:       Get the error status of the CAN channel
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \param[out]:  tec: send error count
* \return:      exception return -1, see "CAN_ERROR_E", Bitwise OR, no error return 0
**********************************************************************************/
INT32S hal_can_geterrorsts(INT32U com, INT32U *tec);


/**********************************************************************************
* \brief:       Abort the sending of the current channel packet
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \return:      -1: abnormal, success: 0
**********************************************************************************/
INT32S hal_can_abortsend(INT32U com);



/**********************************************************************************
* \brief:       Read CAN data
* \param[in]:   com: CAN channel, see "CAN_COM_E"
* \param[out]:  candata: The storage address of the read data
* \return:      -1: abnormal, success: The number of packets of data read
**********************************************************************************/
INT32S hal_can_readdata(INT32U com, CAN_DATA_T *candata);



/**********************************************************************************
* \brief:       Initialize can driver
* \param[in]:   none
* \return:      none
**********************************************************************************/
void hal_can_initdrv(void);



#endif




